import logging
from typing import Optional, Dict, Any, List
from .obs_client import OBSClient


class VideoController:
    """视频播放控制器 - 控制OBS中已存在的媒体源"""
    
    def __init__(self, obs_client: OBSClient):
        """
        初始化视频控制器
        
        Args:
            obs_client: OBS客户端实例
        """
        self.obs_client = obs_client
        self.logger = logging.getLogger(__name__)
        
    def get_media_sources(self, scene_name: str = None) -> List[str]:
        """
        获取指定场景中的所有媒体源名称
        
        Args:
            scene_name: 场景名称，如果为None则使用当前场景
            
        Returns:
            List[str]: 媒体源名称列表
        """
        if not self.obs_client.is_connected():
            self.logger.error("OBS未连接")
            return []
        
        try:
            # 如果未指定场景，使用当前场景
            if scene_name is None:
                scene_name = self.obs_client.get_current_scene()
                if not scene_name:
                    self.logger.error("无法获取当前场景")
                    return []
            
            # 获取场景项列表
            scene_items = self.obs_client.get_source_list(scene_name)
            if not scene_items:
                return []
            
            # 筛选媒体源
            media_sources = []
            for item in scene_items:
                source_name = item.get('sourceName')
                if source_name:
                    # 检查是否为媒体源
                    try:
                        # 尝试获取媒体状态，如果成功则是媒体源
                        self.obs_client.ws.get_media_input_status(source_name)
                        media_sources.append(source_name)
                    except:
                        # 不是媒体源，跳过
                        continue
            
            return media_sources
            
        except Exception as e:
            self.logger.error(f"获取媒体源列表失败: {e}")
            return []
    
    def check_source_exists(self, source_name: str, scene_name: str = None) -> bool:
        """
        检查媒体源是否存在
        
        Args:
            source_name: 媒体源名称
            scene_name: 场景名称，如果为None则使用当前场景
            
        Returns:
            bool: 媒体源是否存在
        """
        media_sources = self.get_media_sources(scene_name)
        return source_name in media_sources
    
    def play_video(self, source_name: str) -> bool:
        """
        播放视频（从头开始）
        
        Args:
            source_name: 媒体源名称（必须是OBS中已存在的媒体源）
            
        Returns:
            bool: 是否播放成功
        """
        if not self.obs_client.is_connected():
            self.logger.error("OBS未连接")
            return False
        
        if not self.check_source_exists(source_name):
            self.logger.error(f"媒体源不存在: {source_name}")
            return False
        
        try:
            # 重新启动媒体源来播放视频
            self.obs_client.ws.trigger_media_input_action(
                source_name,
                "OBS_WEBSOCKET_MEDIA_INPUT_ACTION_RESTART"
            )
            
            self.logger.info(f"开始播放视频: {source_name}")
            return True
            
        except Exception as e:
            self.logger.error(f"播放视频失败: {e}")
            return False
    
    def pause_video(self, source_name: str) -> bool:
        """
        暂停视频
        
        Args:
            source_name: 媒体源名称（必须是OBS中已存在的媒体源）
            
        Returns:
            bool: 是否暂停成功
        """
        if not self.obs_client.is_connected():
            self.logger.error("OBS未连接")
            return False
        
        if not self.check_source_exists(source_name):
            self.logger.error(f"媒体源不存在: {source_name}")
            return False
        
        try:
            self.obs_client.ws.trigger_media_input_action(
                source_name,
                "OBS_WEBSOCKET_MEDIA_INPUT_ACTION_PAUSE"
            )
            
            self.logger.info(f"暂停视频: {source_name}")
            return True
            
        except Exception as e:
            self.logger.error(f"暂停视频失败: {e}")
            return False
    
    def stop_video(self, source_name: str) -> bool:
        """
        停止视频
        
        Args:
            source_name: 媒体源名称（必须是OBS中已存在的媒体源）
            
        Returns:
            bool: 是否停止成功
        """
        if not self.obs_client.is_connected():
            self.logger.error("OBS未连接")
            return False
        
        if not self.check_source_exists(source_name):
            self.logger.error(f"媒体源不存在: {source_name}")
            return False
        
        try:
            self.obs_client.ws.trigger_media_input_action(
                source_name,
                "OBS_WEBSOCKET_MEDIA_INPUT_ACTION_STOP"
            )
            
            self.logger.info(f"停止视频: {source_name}")
            return True
            
        except Exception as e:
            self.logger.error(f"停止视频失败: {e}")
            return False
    
    def resume_video(self, source_name: str) -> bool:
        """
        恢复播放视频
        
        Args:
            source_name: 媒体源名称（必须是OBS中已存在的媒体源）
            
        Returns:
            bool: 是否恢复成功
        """
        if not self.obs_client.is_connected():
            self.logger.error("OBS未连接")
            return False
        
        if not self.check_source_exists(source_name):
            self.logger.error(f"媒体源不存在: {source_name}")
            return False
        
        try:
            self.obs_client.ws.trigger_media_input_action(
                source_name,
                "OBS_WEBSOCKET_MEDIA_INPUT_ACTION_PLAY"
            )
            
            self.logger.info(f"恢复播放视频: {source_name}")
            return True
            
        except Exception as e:
            self.logger.error(f"恢复播放视频失败: {e}")
            return False
    
    def set_video_visibility(self, source_name: str, visible: bool, scene_name: str = None) -> bool:
        """
        设置视频源可见性
        
        Args:
            source_name: 媒体源名称
            visible: 是否可见
            scene_name: 场景名称，如果为None则使用当前场景
            
        Returns:
            bool: 是否设置成功
        """
        if not self.obs_client.is_connected():
            self.logger.error("OBS未连接")
            return False
        
        try:
            # 如果未指定场景，使用当前场景
            if scene_name is None:
                scene_name = self.obs_client.get_current_scene()
                if not scene_name:
                    self.logger.error("无法获取当前场景")
                    return False
            
            # 获取场景项ID
            scene_items = self.obs_client.get_source_list(scene_name)
            if not scene_items:
                self.logger.error(f"无法获取场景项列表: {scene_name}")
                return False
            
            # 查找指定源的场景项ID
            item_id = None
            for item in scene_items:
                if item.get('sourceName') == source_name:
                    item_id = item.get('sceneItemId')
                    break
            
            if item_id is None:
                self.logger.error(f"未找到媒体源: {source_name}")
                return False
            
            # 设置可见性
            self.obs_client.ws.set_scene_item_enabled(
                scene_name=scene_name,
                scene_item_id=item_id,
                scene_item_enabled=visible
            )
            
            action = "显示" if visible else "隐藏"
            self.logger.info(f"{action}视频源: {source_name}")
            return True
            
        except Exception as e:
            self.logger.error(f"设置视频源可见性失败: {e}")
            return False
    
    def get_media_status(self, source_name: str) -> Optional[Dict[str, Any]]:
        """
        获取媒体源状态
        
        Args:
            source_name: 媒体源名称
            
        Returns:
            Dict: 媒体状态信息
        """
        if not self.obs_client.is_connected():
            self.logger.error("OBS未连接")
            return None
        
        try:
            response = self.obs_client.ws.get_media_input_status(source_name)
            # 处理不同类型的响应格式
            if hasattr(response, 'attrs') and callable(response.attrs):
                attrs = response.attrs()
                # 如果attrs返回的是列表，尝试转换为dict
                if isinstance(attrs, list) and len(attrs) > 0:
                    if hasattr(attrs[0], '__dict__'):
                        return attrs[0].__dict__
                    else:
                        return {"media_data": attrs}
                elif isinstance(attrs, dict):
                    return attrs
                else:
                    return {"raw_data": attrs}
            elif hasattr(response, '__dict__'):
                return response.__dict__
            else:
                return {"raw_response": str(response)}
        except Exception as e:
            self.logger.error(f"获取媒体状态失败: {e}")
            return None
    
    def update_video_file(self, source_name: str, new_video_path: str) -> bool:
        """
        更新媒体源的视频文件（可选功能）
        
        Args:
            source_name: 媒体源名称（必须是OBS中已存在的媒体源）
            new_video_path: 新的视频文件路径
            
        Returns:
            bool: 是否更新成功
        """
        if not self.obs_client.is_connected():
            self.logger.error("OBS未连接")
            return False
        
        if not self.check_source_exists(source_name):
            self.logger.error(f"媒体源不存在: {source_name}")
            return False
        
        try:
            # 更新媒体源设置
            settings = {
                "local_file": new_video_path
            }
            
            self.obs_client.ws.set_input_settings(
                input_name=source_name,
                input_settings=settings
            )
            
            self.logger.info(f"更新视频文件: {source_name} -> {new_video_path}")
            return True
            
        except Exception as e:
            self.logger.error(f"更新视频文件失败: {e}")
            return False